package com.gwcm.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwcm.exception.BusinessException;
import com.gwcm.mapper.RoleMapper;
import com.gwcm.mapper.RoleMenuMapper;
import com.gwcm.model.dto.menu.MenuQueryRequest;
import com.gwcm.model.entity.Menu;
import com.gwcm.model.entity.Role;
import com.gwcm.model.vo.MenuVo;
import com.gwcm.model.vo.MetaVo;
import com.gwcm.model.vo.RoleVo;
import com.gwcm.model.vo.RouterVo;
import com.gwcm.service.IMenuService;
import com.gwcm.mapper.MenuMapper;
import com.gwcm.util.PageUtil;
import com.yhz.commonutil.common.ErrorCode;
import com.yhz.commonutil.constant.SortConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
* @author 15375
* @description 针对表【menu(菜单权限表)】的数据库操作Service实现
* @createDate 2023-05-04 17:17:25
*/
@Service
public class IMenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
    implements IMenuService {
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleMenuMapper roleMenuMapper;

    /**
     * 参数查询菜单列表
     * @param menu 菜单对象
     * @return 菜单列表
     */
    @Override
    public List<Menu> selectMenuList(Menu menu){
        List<Menu> menuList = menuMapper.selectMenuList(menu);
//        List<Menu> treeMenuList = this.buildTreeMenu(menuList);
        return menuList;
    }

    /**
     * 构建树形菜单
     * @param menus
     * @return
     */
    private List<Menu> buildTreeMenu(List<Menu> menus) {
        List<Menu> finalMenus = new ArrayList<>();
        for(Menu menu : menus) {
            for(Menu e : menus) {
                if(menu.getId() == e.getParentId()) {
                    menu.getChildren().add(e);
                }
            }
            if(menu.getParentId() == 0L) { // 提取出父节点
                finalMenus.add(menu);
            }
        }
        return finalMenus;
    }

    /**
     * 查询所有目录+菜单
     * @return 树形菜单
     */
    @Override
    public List<Menu> selectAllMenuTree(){
        List<Menu> menuList = menuMapper.selectAllMenuTree();
        List<Menu> treeMenuList = this.buildTreeMenu(menuList);
        return treeMenuList;
    }

    /**
     * 根据userId查询菜单列表
     * @param userId
     * @return 菜单列表
     */
    @Override
    public List<Menu> selectMenuListByUserId(Long userId){
        List<Menu> menuList = null;
        // 管理员显示所有菜单信息
        if(userId == 1L){
            menuList = selectMenuList(new Menu());
        } else{
            menuList = buildTreeMenu(menuMapper.selectMenuTreeByUserId(userId));
        }
        return menuList;
    }

    /**
     * 根据用户ID查询权限信息
     * @param userId
     * @return
     */
    @Override
    public Set<String> selectMenuPermsByUserId(Long userId){
        List<String> perms;
        // 管理员获得所有权限码
        if(userId == 1L) {
            perms = menuMapper.selectMenuPerms();
        } else {
            perms = menuMapper.selectMenuPermsByUserId(userId);
        }
        Set<String> permSet = new HashSet<>(); // 使用set去重

        for(String perm : perms){
            if(StrUtil.isNotEmpty(perm)){
                permSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permSet;
    }

    /**
     * 根据roleID查询menuIds
     * @param roleId 角色ID
     * @return 选中的menuIds
     */
    @Override
    public List<Long> selectMenuIdsByRoleId(Long roleId){
        Role role = roleMapper.selectRoleById(roleId);
        return menuMapper.selectMenuIdsByRoleId(roleId);
    }

    /**
     * 得到动态路由
     * @param userId
     * @return
     */
    @Override
    public List<RouterVo> getRouters(Long userId){
        List<Menu> treeMenuListOfLoginUser = selectMenuListByUserId(userId);
        List<RouterVo> routerVos = this.buildRouters(treeMenuListOfLoginUser);
        return routerVos;
    }

    /**
     * 构建路由
     * @param menuTree
     * @return
     */
    private List<RouterVo> buildRouters(List<Menu> menuTree) {
        List<RouterVo> routerVos = new ArrayList<>();
        menuTree.forEach(menu -> {
            RouterVo routerVo = new RouterVo();
            routerVo.setPath(this.getRouterPath(menu));
            routerVo.setHidden("1".equals(menu.getVisible()));
            routerVo.setComponent(this.getRouterComponent(menu));
            String path = menu.getPath();
            // system -> System
            String name = path.substring(0,1).toUpperCase() + path.substring(1);
            routerVo.setName(name);
            MetaVo meta = new MetaVo();
            meta.setTitle(menu.getMenuName());
            meta.setIcon(menu.getIcon());
            routerVo.setMeta(meta);
            if(menu.getChildren().size() > 0 && "M".equals(menu.getMenuType())){
                routerVo.setRedirect("noRedirect");
                // 子节点调用当前方法进行再次转换
                routerVo.setChildren(buildRouters(menu.getChildren()));
            }
            routerVos.add(routerVo);
        });
        return routerVos;
    }

    /**
     * 获取路由地址
     * @param menu 菜单信息
     * @return 路由地址
     */
    private String getRouterPath(Menu menu) {
        String routerPath = menu.getPath();
        // M 代表目录
        if(0 == menu.getParentId().intValue() && "M".equals(menu.getMenuType())){
            routerPath = "/" + menu.getPath();
        }
        return routerPath;
    }

    /**
     * 获取组件信息
     * @param menu 菜单信息
     * @return 组件信息
     */
    private String getRouterComponent(Menu menu) {
        String component = "Layout";
        // C 代表菜单
        if(StrUtil.isNotEmpty(menu.getComponent()) && "C".equals(menu.getMenuType())){
            component = menu.getComponent();
        }
        return component;
    }

    /**
     * 根据menuId查询menu
     * @param menuId 菜单ID
     * @return 菜单信息
     */
    @Override
    public Menu selectMenuById(Long menuId){
        return menuMapper.selectMenuById(menuId);
    }

    /**
     * 根据menuId判断是否存在子菜单
     * @param menuId 菜单ID
     * @return 结果 true 存在 false 不存在
     */
    private boolean hasChildByMenuId(Long menuId) {
        int result = menuMapper.hasChildByMenuId(menuId);
        return result > 0 ? true : false;
    }

    /**
     * 根据menuId判断是否存有角色
     * @param menuId 菜单ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkMenuExistRole(Long menuId){
        int result = roleMenuMapper.checkMenuExistRole(menuId);
        return result > 0 ? true : false;
    }

    /**
     * 判断menuName是否唯一
     * @param menuName
     * @return 结果
     */
    @Override
    public boolean checkMenuNameUnique(String menuName){
        Menu info = menuMapper.checkMenuNameUnique(menuName);
        return info == null ? true : false;
    }

//    /**
//     * 新增菜单
//     * @param menu
//     * @return 结果
//     */
//    @Override
//    public int insertMenu(Menu menu){
//        int row = 0;
//        if(checkMenuNameUnique(menu.getMenuName())){
//            row = menuMapper.insertMenu(menu);
//        }
//        return row;
//    }

    /**
     * 新增菜单
     * @param menu
     */
    @Override
    public void saveMenu(Menu menu){
        String menuName = menu.getMenuName();
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<>();
        menuQueryWrapper.eq("menu_name",menuName);
        Menu selectOne = baseMapper.selectOne(menuQueryWrapper);
        if(!ObjectUtil.isEmpty(selectOne)){
            throw new BusinessException("菜单名称已存在",50000, "");
        }
        int insert = baseMapper.insert(menu);
        if(insert < 1){
            throw new BusinessException(ErrorCode.SAVE_ERROR);
        }
    }

//    /**
//     * 修改菜单
//     * @param menu
//     * @return 结果
//     */
//    @Override
//    public int updateMenu(Menu menu){
//        return menuMapper.updateMenu(menu);
//    }

    /**
     * 修改菜单
     * @param menu
     */
    @Override
    public void updateMenu(Menu menu){
        String menuName = menu.getMenuName();
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<>();
        menuQueryWrapper.eq("menu_name", menuName);
        Menu selectOne = baseMapper.selectOne(menuQueryWrapper);
        if(!ObjectUtil.isEmpty(selectOne)){
            throw new BusinessException("菜单名称已存在", 50000, "");
        }
        int update = baseMapper.updateById(menu);
        if(update < 1){
            throw new BusinessException(ErrorCode.UPDATE_ERROR);
        }
//        String roleName = role.getRoleName();
//        String roleKey = role.getRoleKey();
//        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
//        roleQueryWrapper.eq("role_name", roleName);
//        Role selectOne = baseMapper.selectOne(roleQueryWrapper);
//        if (!ObjectUtil.isEmpty(selectOne) || checkRoleKeyUnique(roleKey)) {
//            throw new BusinessException("角色名称或角色权限已存在", 50000, "");
//        }
//        int update = baseMapper.updateById(role);
//        if (update < 1) {
//            throw new BusinessException(ErrorCode.UPDATE_ERROR);
//        }
    }

    /**
     * 根据menuId删除菜单
     * @param menuId
     * @return 结果
     */
    @Override
    public int deleteMenuById(Long menuId){
        return menuMapper.deleteMenuById(menuId);
    }


}




